#pragma once

inline LUnknown * LCardPtrAssign(LUnknown ** pp, LUnknown * lp)
{
	if ( pp == NULL )
		return NULL;

	if ( lp != NULL )
		lp->AddRef();
	if ( *pp )
		(*pp)->Release();
	*pp = lp;
	return lp;
}

template <class T>
class CLCardPtr : public CComPtr<T>
{
public:

	CLCardPtr(void) throw() {}

	CLCardPtr(int nNull) throw() : CComPtr<T>(nNull) {}

	CLCardPtr(T * lp) throw() : CComPtr<T>(lp) {}

	CLCardPtr(const CLCardPtr<T> & lp) throw() : CComPtr<T>(lp.p) {}

	T * operator = (T* lp) throw()
	{
		if ( *this != lp )
		{
			return static_cast < T * > ( LCardPtrAssign((LUnknown**)&p, lp) );
		}
		return *this;
	}

	T * operator = (const CLCardPtr<T> & lp) throw()
	{
		if ( *this != lp )
		{
			return static_cast < T * > ( LCardPtrAssign((LUnknown**)&p, lp) );
		}
		return *this;
	}
private:
	bool IsEqualObject(LUnknown * pOther) throw();
	template <typename Q>
	T * operator = (const CLCardPtr<Q> & lp) throw();
	HRESULT SetSite(LUnknown* punkParent) throw();
	HRESULT Advise(LUnknown* pUnk, const IID& iid, LPDWORD pdw) throw();
	HRESULT CoCreateInstance(REFCLSID rclsid, LUnknown* pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw();
	HRESULT CoCreateInstance(LPCOLESTR szProgID, LUnknown* pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw();
	template <class Q>
	HRESULT QueryInterface(Q** pp) const throw();
};
